home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 726-750 / 741 / rkrm_devices / rkrm_devices.lha / Gameport / Absolute_Joystick.c < prev   
C/C++ Source or Header  |  1992-09-03  |  11KB  |  362 lines

  1. /*
  2.  * Copyright (c) 1992 Commodore-Amiga, Inc.
  3.  * 
  4.  * This example is provided in electronic form by Commodore-Amiga, Inc. for 
  5.  * use with the "Amiga ROM Kernel Reference Manual: Devices", 3rd Edition, 
  6.  * published by Addison-Wesley (ISBN 0-201-56775-X).
  7.  * 
  8.  * The "Amiga ROM Kernel Reference Manual: Devices" contains additional 
  9.  * information on the correct usage of the techniques and operating system 
  10.  * functions presented in these examples.  The source and executable code 
  11.  * of these examples may only be distributed in free electronic form, via 
  12.  * bulletin board or as part of a fully non-commercial and freely 
  13.  * redistributable diskette.  Both the source and executable code (including 
  14.  * comments) must be included, without modification, in any copy.  This 
  15.  * example may not be published in printed form or distributed with any
  16.  * commercial product.  However, the programming techniques and support
  17.  * routines set forth in these examples may be used in the development
  18.  * of original executable software products for Commodore Amiga computers.
  19.  * 
  20.  * All other rights reserved.
  21.  * 
  22.  * This example is provided "as-is" and is subject to change; no
  23.  * warranties are made.  All use is at your own risk. No liability or
  24.  * responsibility is assumed.
  25.  *
  26.  ****************************************************************************
  27.  *
  28.  * Absolute_Joystick.c
  29.  *
  30.  * Gameport device absolute joystick example
  31.  *
  32.  * Compile with SAS 5.10  lc -b1 -cfistq -v -y -L
  33.  *
  34.  * Run from CLI only
  35.  */
  36.  
  37. #include <exec/types.h>
  38. #include <exec/io.h>
  39. #include <exec/memory.h>
  40. #include <intuition/intuition.h>
  41. #include <exec/exec.h>
  42. #include <dos/dos.h>
  43. #include <devices/gameport.h>
  44. #include <devices/inputevent.h>
  45.  
  46. #include <clib/exec_protos.h>
  47. #include <clib/alib_protos.h>
  48. #include <clib/dos_protos.h>
  49. #include <clib/intuition_protos.h>
  50.  
  51. #include <stdio.h>
  52.  
  53. #ifdef LATTICE
  54. int CXBRK(void) { return(0); }     /* Disable SAS CTRL/C handling */
  55. int chkabort(void) { return(0); }  /* really */
  56. #endif
  57.  
  58. #define JOY_X_DELTA (1)
  59. #define JOY_Y_DELTA (1)
  60. #define TIMEOUT_SECONDS (10)
  61.  
  62. extern struct ExecBase *SysBase;
  63.  
  64. /*-----------------------------------------------------------------------
  65. ** Routine to print out some information for the user.
  66. */
  67. VOID printInstructions(VOID)
  68. {
  69. printf("\n >>> gameport.device Absolute Joystick Demo <<<\n\n");
  70.  
  71. if (SysBase->VBlankFrequency==60)
  72.     printf(" Running on NTSC system (60 Hz).\n");
  73. else if (SysBase->VBlankFrequency==50)
  74.     printf(" Running on PAL system (50 Hz).\n");
  75.  
  76. printf( " Attach joystick to rear connector (A3000) and (A1000).\n"
  77.         " Attach joystick to right connector (A2000).\n"
  78.         " Attach joystick to left connector (A500).\n"
  79.     " Then move joystick and click its button(s).\n\n"
  80.     " To exit program press and release fire button 3 consecutive times. \n"
  81.     " The program also exits if no activity occurs for 1 minute.\n\n");
  82. }
  83.  
  84.  
  85. /*-----------------------------------------------------------------------
  86. ** print out information on the event received.
  87. */
  88. BOOL check_move(struct InputEvent *game_event)
  89. {
  90. WORD xmove, ymove;
  91. BOOL timeout=FALSE;
  92.  
  93. xmove = game_event->ie_X;
  94. ymove = game_event->ie_Y;
  95.  
  96. if (xmove == 1)
  97.     {
  98.     if (ymove == 1) printf("RIGHT DOWN\n");
  99.     else if (ymove == 0) printf("RIGHT\n");
  100.     else if (ymove ==-1) printf("RIGHT UP\n");
  101.     else printf("UNKNOWN Y\n");
  102.     }
  103. else if (xmove ==-1)
  104.     {
  105.     if (ymove == 1) printf("LEFT DOWN\n");
  106.     else if (ymove == 0) printf("LEFT\n");
  107.     else if (ymove ==-1) printf("LEFT UP\n");
  108.     else printf("UNKNOWN Y\n");
  109.     }
  110. else if (xmove == 0)
  111.     {
  112.     if (ymove == 1) printf("DOWN\n");
  113.     /* Note that 0,0 can be a timeout, or a direction release. */
  114.     else if (ymove == 0)
  115.     {
  116.     if (game_event->ie_TimeStamp.tv_secs >=
  117.             (UWORD)(SysBase->VBlankFrequency) * TIMEOUT_SECONDS)
  118.             {
  119.             /* Under 1.3 (V34) and earlier versions of the Amiga OS, the   */
  120.             /* ie_TimeStamp.tvsecs field used in the if() statement above  */
  121.             /* is not correctly filled in.  Therefore, this program cannot */
  122.             /* tell the difference between a release event and a timeout   */
  123.             /* under 1.3 (release events will be reported as timeouts)     */
  124.         printf("TIMEOUT\n");
  125.         timeout=TRUE;
  126.         }
  127.     else printf("RELEASE\n");
  128.     }
  129.     else if (ymove ==-1) printf("UP\n");
  130.     else printf("UNKNOWN Y\n");
  131.     }
  132. else
  133.     {
  134.     printf("UNKNOWN X ");
  135.     if (ymove == 1) printf("unknown action\n");
  136.     else if (ymove == 0) printf("unknown action\n");
  137.     else if (ymove ==-1) printf("unknown action\n");
  138.     else printf("UNKNOWN Y\n");
  139.     }
  140.  
  141. return(timeout);
  142.  
  143. }
  144.  
  145. /*-----------------------------------------------------------------------
  146. ** send a request to the gameport to read an event.
  147. */
  148. VOID send_read_request( struct InputEvent *game_event,
  149.             struct IOStdReq *game_io_msg)
  150. {
  151. game_io_msg->io_Command = GPD_READEVENT;
  152. game_io_msg->io_Flags    = 0;
  153. game_io_msg->io_Data    = (APTR)game_event;
  154. game_io_msg->io_Length    = sizeof(struct InputEvent);
  155. SendIO(game_io_msg);  /* Asynchronous - message will return later */
  156. }
  157.  
  158. /*-----------------------------------------------------------------------
  159. ** simple loop to process gameport events.
  160. */
  161. VOID processEvents( struct IOStdReq *game_io_msg,
  162.             struct MsgPort  *game_msg_port)
  163. {
  164. BOOL timeout;
  165. SHORT timeouts;
  166. SHORT button_count;
  167. BOOL  not_finished;
  168. struct InputEvent game_event;    /* where input event will be stored */
  169.  
  170. /* From now on, just read input events into the event buffer,
  171. ** one at a time.  READEVENT waits for the preset conditions.
  172. */
  173. timeouts = 0;
  174. button_count = 0;
  175. not_finished = TRUE;
  176.  
  177. while ((timeouts < 6) && (not_finished))
  178.     {
  179.     /* Send the read request */
  180.     send_read_request(&game_event,game_io_msg);
  181.  
  182.     /* Wait for joystick action */
  183.     Wait(1L << game_msg_port->mp_SigBit);
  184.     while (NULL != GetMsg(game_msg_port))
  185.     {
  186.     timeout=FALSE;
  187.     switch(game_event.ie_Code)
  188.         {
  189.         case IECODE_LBUTTON:
  190.         printf(" FIRE BUTTON PRESSED \n");
  191.         break;
  192.  
  193.         case (IECODE_LBUTTON | IECODE_UP_PREFIX):
  194.         printf(" FIRE BUTTON RELEASED \n");
  195.         if (3 == ++button_count)
  196.             not_finished = FALSE;
  197.         break;
  198.  
  199.         case IECODE_RBUTTON:
  200.         printf(" ALT BUTTON PRESSED \n");
  201.         button_count = 0;
  202.         break;
  203.  
  204.         case (IECODE_RBUTTON | IECODE_UP_PREFIX):
  205.         printf(" ALT BUTTON RELEASED \n");
  206.         button_count = 0;
  207.         break;
  208.  
  209.         case IECODE_NOBUTTON:
  210.         /* Check for change in position */
  211.         timeout = check_move(&game_event);
  212.         button_count = 0;
  213.         break;
  214.  
  215.         default:
  216.         break;
  217.         }
  218.  
  219.     if (timeout)
  220.         timeouts++;
  221.     else
  222.         timeouts=0;
  223.     }
  224.     }
  225. }
  226.  
  227. /*-----------------------------------------------------------------------
  228. ** allocate the controller if it is available.
  229. ** you allocate the controller by setting its type to something
  230. ** other than GPCT_NOCONTROLLER.  Before you allocate the thing
  231. ** you need to check if anyone else is using it (it is free if
  232. ** it is set to GPCT_NOCONTROLLER).
  233. */
  234. BOOL set_controller_type(BYTE type, struct IOStdReq *game_io_msg)
  235. {
  236. BOOL success = FALSE;
  237. BYTE controller_type = 0;
  238.  
  239. /* begin critical section
  240. ** we need to be sure that between the time we check that the controller
  241. ** is available and the time we allocate it, no one else steals it.
  242. */
  243. Forbid();
  244.  
  245. game_io_msg->io_Command = GPD_ASKCTYPE;       /* inquire current status */
  246. game_io_msg->io_Flags    = IOF_QUICK;
  247. game_io_msg->io_Data    = (APTR)&controller_type; /* put answer in here */
  248. game_io_msg->io_Length    = 1;
  249. DoIO(game_io_msg);
  250.  
  251. /* No one is using this device unit, let's claim it */
  252. if (controller_type == GPCT_NOCONTROLLER)
  253.     {
  254.     game_io_msg->io_Command = GPD_SETCTYPE;
  255.     game_io_msg->io_Flags   = IOF_QUICK;
  256.     game_io_msg->io_Data    = (APTR)&type;
  257.     game_io_msg->io_Length  = 1;
  258.     DoIO( game_io_msg);
  259.     success = TRUE;
  260.     }
  261.  
  262. Permit(); /* critical section end */
  263. return(success);
  264. }
  265.  
  266. /*-----------------------------------------------------------------------
  267. ** tell the gameport when to trigger.
  268. */
  269. VOID set_trigger_conditions(struct GamePortTrigger *gpt,
  270.                 struct IOStdReq *game_io_msg)
  271. {
  272. /* trigger on all joystick key transitions */
  273. gpt->gpt_Keys    = GPTF_UPKEYS | GPTF_DOWNKEYS;
  274. gpt->gpt_XDelta = JOY_X_DELTA;
  275. gpt->gpt_YDelta = JOY_Y_DELTA;
  276. /* timeout trigger every TIMEOUT_SECONDS second(s) */
  277. gpt->gpt_Timeout = (UWORD)(SysBase->VBlankFrequency) * TIMEOUT_SECONDS;
  278.  
  279. game_io_msg->io_Command = GPD_SETTRIGGER;
  280. game_io_msg->io_Flags    = IOF_QUICK;
  281. game_io_msg->io_Data    = (APTR)gpt;
  282. game_io_msg->io_Length    = (LONG)sizeof(struct GamePortTrigger);
  283. DoIO(game_io_msg);
  284. }
  285.  
  286. /*-----------------------------------------------------------------------
  287. ** clear the buffer.  do this before you begin to be sure you
  288. ** start in a known state.
  289. */
  290. VOID flush_buffer(struct IOStdReq *game_io_msg)
  291. {
  292. game_io_msg->io_Command = CMD_CLEAR;
  293. game_io_msg->io_Flags    = IOF_QUICK;
  294. game_io_msg->io_Data    = NULL;
  295. game_io_msg->io_Length    = 0;
  296. DoIO(game_io_msg);
  297. }
  298.  
  299. /*-----------------------------------------------------------------------
  300. ** free the unit by setting its type back to GPCT_NOCONTROLLER.
  301. */
  302. VOID free_gp_unit(struct IOStdReq *game_io_msg)
  303. {
  304. BYTE type = GPCT_NOCONTROLLER;
  305.  
  306. game_io_msg->io_Command = GPD_SETCTYPE;
  307. game_io_msg->io_Flags    = IOF_QUICK;
  308. game_io_msg->io_Data    = (APTR)&type;
  309. game_io_msg->io_Length    = 1;
  310. DoIO(game_io_msg);
  311. }
  312.  
  313. /*-----------------------------------------------------------------------
  314. ** allocate everything and go.    On failure, free any resources that
  315. ** have been allocated.     this program fails quietly--no error messages.
  316. */
  317. VOID main(int argc,char **argv)
  318. {
  319. struct GamePortTrigger     joytrigger;
  320. struct IOStdReq        *game_io_msg;
  321. struct MsgPort        *game_msg_port;
  322.  
  323. /* Create port for gameport device communications */
  324. if (game_msg_port = CreatePort("RKM_game_port",0))
  325.     {
  326.     /* Create message block for device IO */
  327.     if (game_io_msg = (struct IOStdReq *)
  328.                       CreateExtIO(game_msg_port,sizeof(*game_io_msg)))
  329.     {
  330.     game_io_msg->io_Message.mn_Node.ln_Type = NT_UNKNOWN;
  331.  
  332.     /* Open the right/back (unit 1, number 2) gameport.device unit */
  333.     if (!OpenDevice("gameport.device",1,game_io_msg,0))
  334.         {
  335.         /* Set controller type to joystick */
  336.         if (set_controller_type(GPCT_ABSJOYSTICK,game_io_msg))
  337.         {
  338.         /* Specify the trigger conditions */
  339.         set_trigger_conditions(&joytrigger,game_io_msg);
  340.  
  341.         printInstructions();
  342.  
  343.         /* Clear device buffer to start from a known state.
  344.         ** There might still be events left
  345.         */
  346.         flush_buffer(game_io_msg);
  347.  
  348.         processEvents(game_io_msg,game_msg_port);
  349.  
  350.         /* Free gameport unit so other applications can use it ! */
  351.         free_gp_unit(game_io_msg);
  352.         }
  353.         CloseDevice(game_io_msg);
  354.         }
  355.     DeleteExtIO(game_io_msg);
  356.     }
  357.     DeletePort(game_msg_port);
  358.     }
  359. }
  360.  
  361.  
  362.